// effect 栈，处理嵌套effect的情况用的
const effectStack = []
let activeEffect;

export function effect(fn){
    const effectFn = ()=> {
        try {
            activeEffect = effectFn;
            effectStack.push(effectFn);
            return fn();
        } finally {
            // 用一次就丢掉，就不存在后面一个覆盖前一个情况
            effectStack.pop();
            activeEffect = effectStack[effectStack.length - 1];
        }
    }
    effectFn();
    return effectFn;
}

const targetMap = new WeakMap();
/**
* 值绑定 effect
* @param target 源对象
* @param key 值名称
*/
export function track(target, key){
    if (!activeEffect){
        return;
    }

    let depsMap = targetMap.get(target);
    if (!depsMap){
        targetMap.set(target, (depsMap = new Map()));
    }

    let deps = depsMap.get(key);
    if (!deps){
        depsMap.set(key, (deps = new Set()));
    }
    deps.add(activeEffect);
}
/**
* 根据值调用对应的 effect
* @param target 源对象
* @param key 值名称
*/
export function trigger(target, key){
    const depsMap = targetMap.get(target);
    if (!depsMap) {
        return;
    }
    const deps = depsMap.get(key);
    if (!deps){
        return;
    }
    return deps.forEach((effectFn)=>{
        effectFn();
    });
}